package com.katian.chep.palettes;

import au.com.bytecode.opencsv.CSVReader;
import org.apache.poi.hssf.usermodel.HSSFCellStyle;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.*;

/**
 * User: csavard
 * Date: 13-05-22
 */
public class RapportUtilisationChepPalletUtil {

    public static Map<String, Client> getClient(InputStream input, char delimiter) throws IOException {
        Map<String, Client> clients = new LinkedHashMap<>();

        CSVReader reader = new CSVReader(new InputStreamReader(input), delimiter);
        String[] nextLine;
        int index = 0;
        while ((nextLine = reader.readNext()) != null) {
            if (index > 0) {
                Client client = new Client();
                client.setCode(nextLine[0]);
                client.setBanniere(nextLine[8]);
                client.setClasse(nextLine[35].substring(1, 2));

                Client client1 = clients.get(client.getCode());
                if (client1 != null && (!client1.getCode().equalsIgnoreCase(client.getCode()) || !client1.getBanniere().equalsIgnoreCase(client.getBanniere()) || !client1.getClasse().equalsIgnoreCase(client.getClasse()))) {
                    throw new RuntimeException("Il y a 2 client avec le code: " + client.getCode() + " qui sont différent.");
                } else {
                    clients.put(client.getCode(), client);
                }
            }
            index++;
        }

        return clients;
    }

    public static Map<Long, Commande> getCommandes(InputStream input, char delimiter) throws IOException {
        Map<Long, Commande> commandes = new LinkedHashMap<>();

        CSVReader reader = new CSVReader(new InputStreamReader(input), delimiter);
        try {
            String[] nextLine;
            int index = 0;
            while ((nextLine = reader.readNext()) != null) {
                if (index > 0) {
                    Commande commande = new Commande();
                    commande.setDate(nextLine[7]);
                    commande.setDistributeur(nextLine[3]);
                    commande.setRoute(nextLine[2]);
                    commande.setNoCommande(Long.parseLong(nextLine[0].substring(1, nextLine[0].length() - 1)));
                    commande.setCodeDetaillant(nextLine[4]);
                    commande.setNomDetaillant(nextLine[5]);
                    commande.setCaisses(Double.parseDouble(nextLine[18]));


                    Commande commande1 = commandes.get(commande.getNoCommande());
                    if (commande1 != null) {
                        throw new RuntimeException("Il y a 2 commandes avec le meme numero: " + commande.getNoCommande() + ".");
                    } else {
                        commandes.put(commande.getNoCommande(), commande);
                    }
                }
                index++;
            }
        } finally {
            reader.close();
        }


        return commandes;
    }

    public static XSSFWorkbook generateRapportUtilisationChepPallet(Map<Long, Commande> commandes, Map<String, Client> clients) {
        XSSFWorkbook wb = new XSSFWorkbook();

        XSSFSheet sheet = wb.createSheet("PALETTES-CHEP");

        //Creation de la ligne titre
        XSSFRow titleRow = sheet.createRow(0);
        titleRow.createCell(0).setCellValue("Date");
        titleRow.createCell(1).setCellValue("Distributeur");
        titleRow.createCell(2).setCellValue("Route");
        titleRow.createCell(3).setCellValue("No Commande");
        titleRow.createCell(4).setCellValue("Code détaillant");
        titleRow.createCell(5).setCellValue("Nom détaillant");
        titleRow.createCell(6).setCellValue("Classe");
        titleRow.createCell(7).setCellValue("Bannière");
        titleRow.createCell(8).setCellValue("Caisses");
        titleRow.createCell(9).setCellValue("Nombre de palettes");

        Set<Long> commandeNos = commandes.keySet();

        //Compile les donn/es
        final Map<List, List<Commande>> commandeCompileeMap = new LinkedHashMap<>();

        double caissesNonCompilees = 0;
        for (Long noCommande : commandeNos) {
            Commande commande = commandes.get(noCommande);
            long codeDetaillant = parseCodeDetaillant(commande.getCodeDetaillant());
            String distributeur = commande.getDistributeur();
            Client client = clients.get(commande.getCodeDetaillant());
            String classe = "?";
            if (client != null) {
                classe = client.getClasse();
            } else {
                System.out.println("Pas trouvé de client pour le code détaillant: " + codeDetaillant);
            }

            if (distributeur.equalsIgnoreCase("Delice 2001") || distributeur.equalsIgnoreCase("Sylvain Lane") || distributeur.equalsIgnoreCase("D. Hebert") || distributeur.equalsIgnoreCase("Gestion Lachance")) {
                if (classe.equalsIgnoreCase("A") || classe.equalsIgnoreCase("B") || classe.equalsIgnoreCase("E") || classe.equalsIgnoreCase("?")) {
                    compile(commandeCompileeMap, commande, codeDetaillant, classe);
                } else {
                    caissesNonCompilees += commande.getCaisses();
                }
            } else {
                compile(commandeCompileeMap, commande, codeDetaillant, classe);
            }
        }

        if (caissesNonCompilees > 0.0) {
            System.out.println("Caisses non compilées: " + caissesNonCompilees);
        }
        //Creation des lignes de commandes
        System.out.println("Sort par distributeur");
        int rowIndex = 1;
        List<List> detaillants = new Vector(commandeCompileeMap.keySet());
        Collections.sort(detaillants, new Comparator() {

            @Override
            public int compare(Object o1, Object o2) {
                List<Commande> commandes1 = commandeCompileeMap.get(o1);
                List<Commande> commandes2 = commandeCompileeMap.get(o2);
                return commandes1.get(0).getDistributeur().compareTo(commandes2.get(0).getDistributeur());
            }
        });

        System.out.println("Creation des lignes");
        for (List detaillant : detaillants) {
            long code = (Long) detaillant.get(0);
            String classe = (String) detaillant.get(1);
            createRow(clients, sheet, rowIndex, code, classe, commandeCompileeMap.get(detaillant));
            rowIndex++;
        }


        //Auto resize column
        System.out.println("Auto Resize Colonnes");
        int columIndex = 0;
        XSSFRow row = sheet.getRow(0);
        while (columIndex <= row.getLastCellNum()) {
            sheet.autoSizeColumn(columIndex);
            columIndex++;
        }


        return wb;
    }

    private static void compile(Map<List, List<Commande>> commandeCompileeMap, Commande commande, long codeDetaillant, String classe) {
        List key = new Vector();
        key.add(codeDetaillant);
        key.add(classe);
        key.add(commande.getDate());

        List<Commande> commandeCompilees = commandeCompileeMap.get(key);
        if (commandeCompilees == null) {
            commandeCompilees = new Vector<>();
            commandeCompileeMap.put(key, commandeCompilees);
        }
        commandeCompilees.add(commande);
    }

    private static void createRow(Map<String, Client> clients, XSSFSheet sheet, int rowIndex, long code, String classe, List<Commande> commandes) {
        XSSFRow row = sheet.createRow(rowIndex);

        String date = "";
        String codeDetaillant = "";
        String distributeur = "";
        String route = "";
        String nomDetaillant = "";
        long noCommande = 0;
        long codeDetaillantFinal = 0;
        double caisses = 0.0;
        String banniere = "";
        for (Commande commande : commandes) {
            date = commande.getDate();
            codeDetaillant = commande.getCodeDetaillant();
            distributeur = commande.getDistributeur();
            route = commande.getRoute();
            noCommande = commande.getNoCommande();
            codeDetaillantFinal = parseCodeDetaillant(codeDetaillant);
            nomDetaillant = commande.getNomDetaillant();
            caisses += commande.getCaisses();

            Client client = clients.get(codeDetaillant);
            if (client != null && (banniere == null || banniere.length() == 0 || banniere.length() > client.getBanniere().length())) {
                banniere = client.getBanniere();
            }
        }

        row.createCell(0).setCellValue(date);
        row.createCell(1).setCellValue(distributeur);
        row.createCell(2).setCellValue(route);
        row.createCell(3).setCellValue(noCommande);

        row.createCell(4).setCellValue(codeDetaillantFinal);
        row.createCell(5).setCellValue(nomDetaillant);

        row.createCell(6).setCellValue(classe);
        row.createCell(7).setCellValue(banniere);

        double reste = caisses % 150.0;
        int nbPalettes = (int) caisses / 150;
        if (reste > 0.0) {
            nbPalettes++;
        }

        row.createCell(8).setCellValue(caisses);
        row.createCell(9).setCellValue(nbPalettes);

        if (classe.equalsIgnoreCase("?")) {
            setRowBackground(sheet.getWorkbook(), row, IndexedColors.RED);
        }
    }

    private static long parseCodeDetaillant(String codeDetaillant) {
        long codeDetaillantFinal = -1;
        try {
            if (codeDetaillant.startsWith("[MAGHBSPMAR")) {
                codeDetaillantFinal = 0;
            } else if (codeDetaillant.startsWith("[MAGHBSP")) {
                codeDetaillantFinal = Long.parseLong(codeDetaillant.substring(8, codeDetaillant.length() - 1));
            } else if (codeDetaillant.startsWith("[MA")) {
                codeDetaillantFinal = Long.parseLong(codeDetaillant.substring(3, codeDetaillant.length() - 1));
            } else if (codeDetaillant.endsWith("M]")) {
                codeDetaillantFinal = Long.parseLong(codeDetaillant.substring(1, codeDetaillant.length() - 2));
            } else {
                codeDetaillantFinal = Long.parseLong(codeDetaillant.substring(1, codeDetaillant.length() - 1));
            }
        } catch (Exception e) {
            System.err.println("Impossible de traité le code détaillant: " + codeDetaillant);
        }
        return codeDetaillantFinal;
    }

    private static void setRowBackground(XSSFWorkbook wb, Row row, IndexedColors color) {
        int colIndex = 0;
        while (colIndex < row.getLastCellNum()) {
            Cell cell = row.getCell(colIndex);
            if (cell != null) {
                CellStyle newStyle = wb.createCellStyle();
                newStyle.cloneStyleFrom(cell.getCellStyle());
                newStyle.setFillPattern(HSSFCellStyle.SOLID_FOREGROUND);
                newStyle.setFillForegroundColor(color.getIndex());

                cell.setCellStyle(newStyle);
            }
            colIndex++;
        }
    }
}
